package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PageUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VideoApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Video;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VideoVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SmallVideosService {
    //这个用于文件上传或者下载
    @Autowired
    private FastFileStorageClient client;

    //用于获取storage中nginx地址
    @Autowired
    private FdfsWebServer webServer;

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private VideoApi videoApi;

    /**
     * 上传视频
     * 1.视频封面 2.视频文件
     * */
    public void saveVideos(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        //判断是否没有上传过来
        if(videoFile.isEmpty() || videoThumbnail.isEmpty()){
            throw  new BusinessException(ErrorResult.error());
        }

        //1.视频上传到FastDFS，获取访问地址
        //获取它的文件名
        String filename = videoFile.getOriginalFilename();
        //截取它的后缀名，因为截取刚好到. 要截取后面所以要加1  abc.jpg
        filename = filename.substring(filename.lastIndexOf(".") + 1);
        //文件上传 参数：1.文件输入流  2.文件长度  3.文件后缀名 4.文件元数据
        StorePath storePath = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(), filename, null);
        //获取url
        String videoUrl = webServer.getWebServerUrl() + storePath.getFullPath();


        //2.封面上传到阿里云OSS，获取图片访问地址
        //参数：1.文件名称  2.输入流
        String imagerUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());


        //3.构建对象 一个videos
        Video video = new Video();
        video.setUserId(UserHolder.getUserId());
        video.setPicUrl(imagerUrl);
        video.setVideoUrl(videoUrl);
        //文本，这个app没有这个功能
        video.setText("没有编程就好了");

        //4.调用api保存，存入mongodb
        String videoId = videoApi.save(video);
        //如果报错，返给前端
        if (StringUtils.isEmpty(videoId)){
            throw new BusinessException(ErrorResult.error());
        }
    }

    //查询视频列表
    public PageResult queryVideoList(Integer page, Integer pagesize) {
        //1.首先查询redis里面数据
        String redisKey = Constants.VIDEOS_RECOMMEND + UserHolder.getUserId();
        String redisValue = redisTemplate.opsForValue().get(redisKey);

        //2.判断redis数据是否存在，还要判断redis里面推荐视频vid是否满足本次分页条数
        List<Video>list =new ArrayList<>();
        int redisPages =0;
        if(!StringUtils.isEmpty(redisValue)){
            //3.如果redis数据存在，就根据vid查询推荐数据
            //例如100，101，102，103
            String[] split = redisValue.split(",");
            //判断当前页的起始页小于数组的总数吗
            if((page-1)*pagesize <split.length ){
                List<Long> vids = Arrays.stream(split).skip((page - 1) * pagesize).limit(pagesize)
                        .map(e -> Long.valueOf(e)).collect(Collectors.toList());
                //调用api根据vid数组查询动态数据
                //redis里面数据
                list =videoApi.findMovmentsByVids(vids);
            }
            //根据总数计算总页数,redis查询的总页数
            redisPages= PageUtil.totalPage(split.length, pagesize);
        }
        //4.如果不存在，就去mysql数据库里面查询视频数据
        if (list.isEmpty()){
            //因为传入的page是redis查询之后的，所以要计算出来，不能一来从第二页查询
            //这个是数据库里面数据
            list =videoApi.queryVideoList(page-redisPages,pagesize);
        }

        //5.提取视频列表中所有的用户id
        List<Long> userId = CollUtil.getFieldValues(list, "userId", Long.class);

        //6.根据id，查询用户的详细信息
        Map<Long, UserInfo> map = userInfoApi.findByIds(userId, null);

        //7.构建一个返回值
        List<VideoVo> vos = new ArrayList<>();
        for (Video video : list) {
            UserInfo info = map.get(video.getUserId());
            if(info != null){
                VideoVo vo = VideoVo.init(info, video);
                vos.add(vo);
            }
        }
        return new PageResult(page,pagesize,0L,vos);
    }
}
